﻿package com.fox2d 
{
	import com.fox2d.events.CharEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author Orlando Leite
	 */
	public class LiveObject2D extends Object2D
	{
		protected var container:Sprite = new Sprite();
		
		protected var _boundsWall:Boolean = true;
		protected var _ghost:Boolean = false;
		
		private var lastPosX:Number;
		private var lastPosY:Number;
		
		public function LiveObject2D() 
		{
			addChild( container );
			
			lastPosX = lastPosY = 0;
		}
		
		public function get boundsWall():Boolean
		{
			return _boundsWall;
		}
		
		public function set boundsWall( value:Boolean ):void
		{
			_boundsWall = value;
		}
		
		public function get ghost():Boolean
		{
			return _ghost;
		}
		
		public function set ghost( value:Boolean ):void
		{
			_ghost = value;
		}
		
		public function setPosition( x:Number, y:Number ):void
		{
			super.x = x;
			super.y = y;
		}
		
		override public function set x( value:Number ):void
		{
			var temp:Number = super.x;
			
			if ( value == temp ) return;
			
			super.x = value;
			
			if ( verifyCollision() )
			{
				super.x = temp;
				
				if ( true )
				{
					dispatchEvent( new CharEvent( CharEvent.HIT_WALL ) );
					
					if ( _ghost ) return;
					
					if ( _boundsWall )
					{
						getNearToWallX( temp, value );
					}
				}
				else
				{
					super.x = value;
				}
			}
		}
		
		override public function set y( value:Number ):void
		{
			var temp:Number = super.y;
			
			if ( value == temp ) return;
			
			super.y = value;
			
			if ( verifyCollision() )
			{
				super.y = temp;
				
				if ( !verifyCollision() )
				{
					dispatchEvent( new CharEvent( CharEvent.HIT_WALL ) );
					
					if ( _ghost ) return;
					
					if ( _boundsWall )
					{
						getNearToWallY( temp, value );
					}
				}
				else
				{
					super.y = value;
				}
			}
		}
		
		protected function getNearToWallX( before:Number, after:Number ):void
		{
			var adjust:Boolean = true;
			
			super.x = before;
			
			while ( adjust )
			{
				if ( super.x == after )
				{
					super.x = before;
					adjust = false;
				}
				else if ( super.x < after )
				{
					super.x++;
					
					if ( verifyCollision() )
					{
						super.x--;
						adjust = false;
					}
				}
				else
				{
					super.x--;
					
					if ( verifyCollision() )
					{
						super.x++;
						adjust = false;
					}
				}
			}
		}
		
		protected function getNearToWallY( before:Number, after:Number ):void
		{
			var adjust:Boolean = true;
			
			super.y = before;
			
			while ( adjust )
			{
				if ( super.y == after )
				{
					super.y = before;
					adjust = false;
				}
				else if ( super.y < after )
				{
					super.y++;
					
					if ( verifyCollision() )
					{
						super.y--;
						adjust = false;
					}
				}
				else
				{
					super.y--;
					
					if ( verifyCollision() )
					{
						super.y++;
						adjust = false;
					}
				}
			}
		}
		
		protected function verifyCollision():Boolean
		{
			if ( game.verifyWalkCollision( this ) )
			{
				return true;
			}
			else if ( game.verifyObjectCollision( this ) )
			{
				return true;
			}
			
			return false;
		}
		
		public function hit( object:Object2D ):Boolean
		{
			return false;
		}
		
		override public function die():void
		{
			game.removeLiveObject( this );
		}
		
		public function update():void
		{
			if ( lastPosX != x || lastPosY != y )
			{
				lastPosX = x;
				lastPosY = x;
				dispatchEvent( new CharEvent( CharEvent.POSITION_CHANGED ) );
			}
		}
		
	}
	
}